package jee.boot.common.remote;

import jee.boot.common.utils.SpringContextHolder;
import org.reflections.Reflections;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
@Order(1)
public class LocalProcessInternalRequest implements ApplicationRunner {
    /**
     * 被调用接口终端
     */
    private Map<String, Endpoint> endpointMap = new HashMap<>();

    public Map<String, Endpoint> getEndpointMap() {
        return endpointMap;
    }

    public void setEndpointMap(Map<String, Endpoint> endpointMap) {
        this.endpointMap = endpointMap;
    }

    /**
     * Callback used to run the bean.
     *
     * @param args incoming application arguments
     * @throws Exception on error
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        Reflections reflections = new Reflections("jee.boot");
        Set<Class<?>> classesList = reflections.getTypesAnnotatedWith(RestController.class);
        for (Class<?> cls : classesList) {
            Object controllerBean = SpringContextHolder.getApplicationContext().getBean(cls);
            RequestMapping pathMapping = cls.getAnnotation(RequestMapping.class);
            String path="";
            if(pathMapping!=null && pathMapping.value().length>0){
                path=pathMapping.value()[0];
            }
            Method[] methods = cls.getMethods();
            for (Method m : methods) {
                Endpoint endpoint = new Endpoint();
                endpoint.setClassInstance(controllerBean);
                endpoint.setPath(path);
                endpoint.setMethod(m);
                PostMapping post = m.getAnnotation(PostMapping.class);
                GetMapping get = m.getAnnotation(GetMapping.class);
                RequestMapping request = m.getAnnotation(RequestMapping.class);
                if (post != null&& post.value().length>0) {
                    endpoint.setHttpMethod(HttpMethod.POST);
                    endpoint.setPath(endpoint.getPath() + post.value()[0]);
                } else if (get != null&& get.value().length>0) {
                    endpoint.setHttpMethod(HttpMethod.GET);
                    endpoint.setPath(endpoint.getPath() + get.value()[0]);
                } else if (request != null&& request.value().length>0) {
                    endpoint.setPath(endpoint.getPath() + request.value()[0]);
                } else {
                    continue;
                }
                endpointMap.put(endpoint.getPath(), endpoint);
            }
        }

    }
    class Endpoint {
        private String path;
        private HttpMethod httpMethod;
        private Object classInstance;
        private Method method;

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public HttpMethod getHttpMethod() {
            return httpMethod;
        }

        public void setHttpMethod(HttpMethod httpMethod) {
            this.httpMethod = httpMethod;
        }

        public Object getClassInstance() {
            return classInstance;
        }

        public void setClassInstance(Object classInstance) {
            this.classInstance = classInstance;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }
    }

}
